package com.obelisco.vista.componentes;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import nextapp.echo2.app.Alignment;
import nextapp.echo2.app.Button;
import nextapp.echo2.app.Color;
import nextapp.echo2.app.Extent;
import nextapp.echo2.app.Grid;
import nextapp.echo2.app.Insets;
import nextapp.echo2.app.Row;
import nextapp.echo2.app.event.ActionEvent;
import nextapp.echo2.app.event.ActionListener;
import nextapp.echo2.app.layout.GridLayoutData;
//import ucla.cumlaude.exception.CumLaudeException;

import com.obelisco.exception.ObeliscoException;
import com.obelisco.modelo.data.Operacion;
import com.obelisco.vista.controles.BotonAccion;
import com.obelisco.vista.controles.BotonFuncion;
import com.obelisco.vista.plantillas.VentanaBase;
import com.obelisco.vista.util.BarraHerramientasHelper;

import echopointng.ContainerEx;

public class BarraHerramientas extends ContainerEx {

	private Row barraFunciones;

	private TipoFuncion tipoFuncionActual = TipoFuncion.NINGUNA;

	private Operacion funcionActual = new Operacion();

	private TipoAccion accionSeleccionada = TipoAccion.NINGUNA;

	private TipoVentana tipo = TipoVentana.LISTA;

	private Vector<BarraHerramientasListener> listeners = new Vector<BarraHerramientasListener>();

	private List<BotonFuncion> funciones = new ArrayList<BotonFuncion>();

	private List<BotonAccion> acciones = new ArrayList<BotonAccion>();

	private boolean mostrarSalir = true;
	
	private boolean mostrarAceptar = true;
	
	private boolean mostrarCancelar = true;

	private String textoAyuda;

	private void cerrarVentana() {

		if (getParent().getParent().getParent().getParent() instanceof VentanaBase) {
			VentanaBase f = (VentanaBase) getParent().getParent().getParent().getParent();
			f.salir();
		}

	}

	protected DialogoMensaje dialogoSalir;

	private ActionListener manejadorEventoBotonSalir = new ActionListener() {

		public void actionPerformed(ActionEvent evento) {
			if (evento.getActionCommand() == "SI") {
				cerrarVentana();
			}
			dialogoSalir.salir();
		}
	};

	protected nextapp.echo2.app.event.ActionListener onClickAccion = new ActionListener() {

		public void actionPerformed(ActionEvent e) {

			if (acciones.contains(e.getSource())) {
				accionSeleccionada = ((BotonAccion) e.getSource()).getTipoAccion();
			}

			try {

				if (accionSeleccionada == TipoAccion.ACEPTAR || accionSeleccionada == TipoAccion.CANCELAR) {

					distribuirEventoAccion(accionSeleccionada);

					tipoFuncionActual = TipoFuncion.NINGUNA;
					if (tipo.equals(TipoVentana.LISTA) || tipo.equals(TipoVentana.TRANSACCION) || tipo.equals(TipoVentana.ASISTENTE)) {
						configurarBarra();
					} else if (tipo.equals(TipoVentana.DIALOGO)) {
						cerrarVentana();
					}
				} else if (accionSeleccionada == TipoAccion.SIGUIENTE || accionSeleccionada == TipoAccion.ANTERIOR) {
					tipoFuncionActual = TipoFuncion.NINGUNA;
					distribuirEventoAccion(accionSeleccionada);
				} else if (accionSeleccionada == TipoAccion.SALIR) {
					if (tipoFuncionActual != TipoFuncion.NINGUNA) {
						// TODO: Preguntar si desea cancelar la operacion
						// actual;
						/*
						 * if (MessageBox.Show("Existe una Operacion en Curso
						 * esta Seguro de Salir de la Transaccion?", "Operacion
						 * en Curso", MessageBoxButtons.YesNo,
						 * MessageBoxIcon.Question) == DialogResult.Yes) {
						 * cerrarVentana(); }
						 */

						dialogoSalir = DialogoMensaje
								.mostrar(
										"Mensaje",
										"Existe una Operacion en Curso. Esta Seguro de Salir de la Transaccion?",
										TipoDialogo.CONFIRMACION,
										BotonesDialogo.SI_NO,
										manejadorEventoBotonSalir);

					} else {
						cerrarVentana();
					}
				} else if (accionSeleccionada == TipoAccion.AYUDA) {
					// TODO: Se presenta la documentacion
					DialogoAyuda.mostrar("Ayuda", getTextoAyuda());
				}
			} catch (ObeliscoException ex) {
				if (ex.getNumError() > 0) {					
					DialogoError.mostrar("Error", ex.getNumError());
				} else {
					DialogoError.mostrar("Error", ex.getMessage());
				}
			} catch (Exception ex) {
				// TODO: Presentar los Mensajes de Error que ocurran
				DialogoError.mostrar("Error", ex.getMessage());
				ex.printStackTrace();
			}

		}

	};

	//TODO METODO MODIFICADO POR JOAN
	private void configurarEstadoFuncionesObjetoConseguido() {
		if (tipo == TipoVentana.TRANSACCION) {
			for (Button boton : funciones) {
				boton.setEnabled(false);
			}
			for (BotonFuncion botonFuncion : funciones) {
				if ((botonFuncion.getTipoFuncion() == TipoFuncion.MODIFICAR)||(botonFuncion.getTipoFuncion() == TipoFuncion.ELIMINAR))
					botonFuncion.setEnabled(true);
			}

		}

	}

	private void configurarEstadoFunciones(boolean estado) {
		for (Button boton : funciones) {
			boton.setEnabled(estado);
		}
		if (tipo == TipoVentana.TRANSACCION) {
			for (BotonFuncion botonFuncion : funciones) {
				if (botonFuncion.getTipoFuncion() == TipoFuncion.INCLUIR
						|| botonFuncion.getTipoFuncion() == TipoFuncion.ELIMINAR
						|| botonFuncion.getTipoFuncion() == TipoFuncion.MODIFICAR
						|| botonFuncion.getTipoFuncion() == TipoFuncion.DEFINIDA_USUARIO) {
					botonFuncion.setEnabled(false);
				}
			}
		}
	}

	private void configurarEstadoAcciones(boolean estado) {
		for (BotonAccion botonAccion : acciones) {
			if (botonAccion.getTipoAccion() == TipoAccion.ACEPTAR
					|| botonAccion.getTipoAccion() == TipoAccion.CANCELAR) {
				botonAccion.setEnabled(estado);
			}
			if (tipo == TipoVentana.ASISTENTE) {
				if (botonAccion.getTipoAccion() == TipoAccion.SALIR
						|| botonAccion.getTipoAccion() == TipoAccion.ANTERIOR) {
					botonAccion.setEnabled(true);
				}
			}
		}
	}

	private void manejarSeleccionFuncion() {
		try {
			if (tipoFuncionActual == TipoFuncion.INCLUIR
					|| tipoFuncionActual == TipoFuncion.MODIFICAR
					|| tipoFuncionActual == TipoFuncion.ELIMINAR
					|| tipoFuncionActual == TipoFuncion.BUSCAR
					|| tipoFuncionActual == TipoFuncion.NINGUNA
					|| tipoFuncionActual == TipoFuncion.DEFINIDA_USUARIO) {

				distribuirEventoFuncion(tipoFuncionActual, funcionActual.getNombre());
				if (tipo.equals(TipoVentana.TRANSACCION)) {
					if (tipoFuncionActual == TipoFuncion.NINGUNA) {
						configurarBarraTipoTransaccion();
					}
					else if (tipoFuncionActual == TipoFuncion.BUSCAR) {
						configurarEstadoFuncionesObjetoConseguido();
					}
					//TODO ELSE AGREGADO POR JOAN
					else if (tipoFuncionActual == TipoFuncion.INCLUIR) {
						for (BotonFuncion botonFuncion : funciones) {
								botonFuncion.setEnabled(false);
						}
					} 
					else if (tipoFuncionActual == TipoFuncion.ELIMINAR) {
						for (BotonFuncion botonFuncion : funciones) {
								botonFuncion.setEnabled(false);
						}
						for (BotonFuncion botonFuncion : funciones) {
							if (botonFuncion.getTipoFuncion() == TipoFuncion.BUSCAR)
								botonFuncion.setEnabled(true);
						}
					} 
				}
				
				// TODO: Si se necesita llamar al Catalogo Ubicarlo en este
				// Evento
				/*
				 * } else if (funcionSeleccionada == TipoFuncion.BUSCAR) { // Si
				 * el Catalogo es Distinto de Nulo es necesario
				 */
			} else if (tipoFuncionActual == TipoFuncion.IMPRIMIR) {
				distribuirEventoFuncion(tipoFuncionActual, funcionActual.getNombre());
			} else {
				// Funciones personalizadas del Usuario
				distribuirEventoFuncion(tipoFuncionActual, funcionActual.getNombre());
			}
		} catch (ObeliscoException ex) {
			if (ex.getNumError() > 0) {
				DialogoError.mostrar("Error", ex.getNumError());
			} else {
				DialogoError.mostrar("Error", ex.getMessage());
			}
		} catch (Exception ex) {
			// TODO: Debe mostrarse en un componente de mensajes el
			// error que ocurrio
			DialogoError.mostrar("Error", ex.getMessage());
			ex.printStackTrace();

		}

	}

	protected nextapp.echo2.app.event.ActionListener onClickFuncion = new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			for (BotonFuncion botonFuncion : funciones) {
				if (botonFuncion.equals(e.getSource())) {
					tipoFuncionActual = botonFuncion.getTipoFuncion();
					funcionActual = botonFuncion.getFuncion();
					break;
				}
			}
			manejarSeleccionFuncion();
			if (tipo == TipoVentana.LISTA) {
				tipoFuncionActual = TipoFuncion.NINGUNA;
				funcionActual = new Operacion();
			}
		}
	};

	public BarraHerramientas() {
		super();
		initComponents();
	}

	private void configurarBarraTipoLista() {
		for (Button boton : funciones) {
			boton.setVisible(false);
		}

		for (BotonFuncion botonFuncion : funciones) {
			if (botonFuncion.getTipoFuncion() == TipoFuncion.INCLUIR
					|| botonFuncion.getTipoFuncion() == TipoFuncion.MODIFICAR
					|| botonFuncion.getTipoFuncion() == TipoFuncion.ELIMINAR
					|| botonFuncion.getTipoFuncion() == TipoFuncion.BUSCAR
					|| botonFuncion.getTipoFuncion() == TipoFuncion.IMPRIMIR
					|| botonFuncion.getTipoFuncion() == TipoFuncion.DEFINIDA_USUARIO) {

				botonFuncion.setVisible(true);
			}

		}
		configurarEstadoFunciones(true);
		for (BotonAccion botonAccion : acciones) {
			if (botonAccion.getTipoAccion() == TipoAccion.SALIR
					|| botonAccion.getTipoAccion() == TipoAccion.AYUDA) {
				botonAccion.setVisible(true);
			} else {
				botonAccion.setVisible(false);
			}
		}
	}

	private void configurarBarraTipoTransaccion() {
		for (Button boton : funciones) {
			boton.setVisible(true);
			//boton.setVisible(false);
		}
		configurarEstadoFunciones(true);
		for (BotonAccion botonAccion : acciones) {
			botonAccion.setVisible(true);
			if (botonAccion.getTipoAccion() == TipoAccion.SIGUIENTE
					|| botonAccion.getTipoAccion() == TipoAccion.ANTERIOR) {
				botonAccion.setVisible(false);
			}
		}
		configurarEstadoAcciones(true);
	}

	private void configurarBarraTipoDialogo() {
		for (Button boton : funciones) {
			boton.setVisible(false);
		}
		for (BotonAccion botonAccion : acciones) {
			botonAccion.setVisible(false);
			if (botonAccion.getTipoAccion() == TipoAccion.ACEPTAR|| botonAccion.getTipoAccion() == TipoAccion.CANCELAR) {
				botonAccion.setVisible(true);
			}
			//JOAN
			if (botonAccion.getTipoAccion() == TipoAccion.ACEPTAR && tipoFuncionActual == TipoFuncion.BUSCAR) {
				botonAccion.setVisible(false);
			}
		}
		configurarEstadoAcciones(true);
	}
	
	private void configurarBarraTipoReporte() {
		for (BotonFuncion boton : funciones) {
			boton.setVisible(false);
			if (boton.getTipoFuncion() == TipoFuncion.IMPRIMIR)
			{
				boton.setVisible(true);
			}
		}		
		configurarEstadoFunciones(true);
		for (BotonAccion botonAccion : acciones) {
			if ( (!(botonAccion.getTipoAccion() == TipoAccion.SALIR) && (!(botonAccion.getTipoAccion() == TipoAccion.CANCELAR) ))) {
				botonAccion.setVisible(false);
			}
		}
	}

	private void configurarBarraTipoAsistente() {
		for (Button boton : funciones) {
			boton.setVisible(false);
		}
		for (BotonAccion botonAccion : acciones) {
			botonAccion.setVisible(false);
			if (botonAccion.getTipoAccion() == TipoAccion.SIGUIENTE
					|| botonAccion.getTipoAccion() == TipoAccion.ANTERIOR
					|| botonAccion.getTipoAccion() == TipoAccion.SALIR) {
				botonAccion.setVisible(true);
			}
		}
		configurarEstadoAcciones(false);
	}

	private void configurarBarra() {
		if (this.tipo.equals(TipoVentana.LISTA)) {
			this.configurarBarraTipoLista();
		} else if (this.tipo.equals(TipoVentana.TRANSACCION)) {
			this.configurarBarraTipoTransaccion();
		} else if (this.tipo.equals(TipoVentana.DIALOGO)) {
			this.configurarBarraTipoDialogo();
		} else if (this.tipo.equals(TipoVentana.ASISTENTE)) {
			this.configurarBarraTipoAsistente();
		} else if (this.tipo.equals(TipoVentana.REPORTE)) {
			this.configurarBarraTipoReporte();
		}
		
		if (mostrarAceptar == false)
		{
			configurarAceptar(false);
		}
		
		if (mostrarCancelar == false)
		{
			configurarCancelar(false);
		}
	}

	private void dibujarFunciones() {
		barraFunciones.removeAll();
		for (BotonFuncion btn : funciones) {
			btn.addActionListener(onClickFuncion);
			barraFunciones.add(btn);
		}
	}

	protected void initComponents() {

		Grid barra = new Grid();
		barra.setWidth(new Extent(100, Extent.PERCENT));
		add(barra);

		barraFunciones = new Row();
		GridLayoutData layoutData = new GridLayoutData();
		layoutData.setBackground(new Color(0xeef1f6));
		layoutData.setInsets(new Insets(new Extent(8, Extent.PX), new Extent(2,Extent.PX), new Extent(0, Extent.PX), new Extent(2,Extent.PX)));
		barraFunciones.setLayoutData(layoutData);
		barraFunciones.setCellSpacing(new Extent(4, Extent.PX));

		barra.add(barraFunciones);

		Row barraAcciones = new Row();
		layoutData = new GridLayoutData();
		layoutData.setBackground(new Color(0xeef1f6));
		layoutData.setInsets(new Insets(new Extent(0, Extent.PX), new Extent(2,Extent.PX), new Extent(4, Extent.PX), new Extent(2,Extent.PX)));
		layoutData.setAlignment(new Alignment(Alignment.RIGHT,Alignment.DEFAULT));
		barraAcciones.setLayoutData(layoutData);
		barraAcciones.setCellSpacing(new Extent(4, Extent.PX));
		barra.add(barraAcciones);

		BotonAccion botonAccion = new BotonAccion(TipoAccion.ACEPTAR);
		botonAccion.addActionListener(onClickAccion);
		barraAcciones.add(botonAccion);
		acciones.add(botonAccion);

		botonAccion = new BotonAccion(TipoAccion.CANCELAR);
		botonAccion.addActionListener(onClickAccion);
		barraAcciones.add(botonAccion);
		acciones.add(botonAccion);

		botonAccion = new BotonAccion(TipoAccion.AYUDA);
		botonAccion.addActionListener(onClickAccion);
		barraAcciones.add(botonAccion);
		acciones.add(botonAccion);

		botonAccion = new BotonAccion(TipoAccion.ANTERIOR);
		botonAccion.addActionListener(onClickAccion);
		barraAcciones.add(botonAccion);
		acciones.add(botonAccion);

		botonAccion = new BotonAccion(TipoAccion.SIGUIENTE);
		botonAccion.addActionListener(onClickAccion);
		barraAcciones.add(botonAccion);
		acciones.add(botonAccion);

		botonAccion = new BotonAccion(TipoAccion.SALIR);
		botonAccion.addActionListener(onClickAccion);
		barraAcciones.add(botonAccion);
		acciones.add(botonAccion);
	}

	protected void distribuirEventoFuncion(TipoFuncion funcion, String nombre) {
		for (BarraHerramientasListener listener : listeners) {
			listener.beforeOnFuncion(funcion, nombre);
			listener.onFuncion(funcion, nombre);
		}
	}

	protected void distribuirEventoAccion(TipoAccion accion) {
		for (BarraHerramientasListener listener : listeners) {
			listener.beforeOnAccion(accion, tipoFuncionActual, funcionActual.getNombre());
			listener.onAccion(accion, tipoFuncionActual, funcionActual.getNombre());
		}
	}

	public void addBarraHerramientasListener(BarraHerramientasListener listener) {
		listeners.add(listener);
	}

	public void removeBarraHerramientasListener(BarraHerramientasListener listener) {
		listeners.remove(listener);
	}

	public TipoVentana getTipo() {
		return tipo;
	}

	public void setTipo(TipoVentana tipo) {
		this.tipo = tipo;		
		setFunciones(BarraHerramientasHelper.getBotonesFuncion(tipo));
	}

	public TipoFuncion getTipoFuncionActual() {
		return tipoFuncionActual;
	}

	public void setTipoFuncionActual(TipoFuncion funcionActual) {
		this.tipoFuncionActual = funcionActual;
	}

	public TipoAccion getAccionSeleccionada() {
		return accionSeleccionada;
	}

	public Operacion getFuncionActual() {
		return funcionActual;
	}

	public void setFuncionActual(Operacion funcionActual) throws ObeliscoException {
		if (getTipo() == TipoVentana.TRANSACCION) {
			this.funcionActual = funcionActual;
			this.tipoFuncionActual = BarraHerramientasHelper.getTipoFuncion(funcionActual);
			manejarSeleccionFuncion();
		} else {
			throw new ObeliscoException(100);
		}
	}

	public void setFuncionActual(TipoFuncion tipoFuncion) throws ObeliscoException {
		if (getTipo() == TipoVentana.TRANSACCION) {
			this.funcionActual = BarraHerramientasHelper.getFuncion(tipoFuncion);
			this.tipoFuncionActual = tipoFuncion;
			manejarSeleccionFuncion();
		} else {
			throw new ObeliscoException(100);
		}
	}

	public void setFuncionActual(String codigo) throws ObeliscoException {
		if (getTipo() == TipoVentana.TRANSACCION) {
			this.funcionActual = BarraHerramientasHelper.getFuncion(codigo);
			this.tipoFuncionActual = BarraHerramientasHelper.getTipoFuncion(this.funcionActual);
			manejarSeleccionFuncion();
		} else {
			throw new ObeliscoException(100);
		}
	}

	public List<BotonFuncion> getFunciones() {
		return funciones;
	}

	public void setFunciones(Vector<BotonFuncion> name) {		
		this.funciones = name;		
		dibujarFunciones();		
		configurarBarra();		
	}

	public boolean isMostrarSalir() {
		return mostrarSalir;
	}

	private void configurarSalir(boolean mostrar) {
		for (BotonAccion boton : acciones) {
			if (boton.getTipoAccion() == TipoAccion.SALIR) {
				boton.setVisible(mostrar);
			}
		}
	}
	
	private void configurarAceptar(boolean mostrar) {
		for (BotonAccion boton : acciones) {
			if (boton.getTipoAccion() == TipoAccion.ACEPTAR) {
				boton.setVisible(mostrar);
			}
		}
	}
	
	private void configurarCancelar(boolean mostrar) {
		for (BotonAccion boton : acciones) {
			if (boton.getTipoAccion() == TipoAccion.CANCELAR) {
				boton.setVisible(mostrar);
			}
		}
	}
	
	private void configurarIncluir(boolean mostrar) {
		for (BotonFuncion boton : funciones) {
			if (boton.getTipoFuncion() == TipoFuncion.INCLUIR) {
				boton.setVisible(mostrar);
			}
		}
	}
	
	public void setMostrarInlcuir(boolean estado) {
		configurarIncluir(estado);
	}
	
	private void configurarModificar(boolean mostrar) {
		for (BotonFuncion boton : funciones) {
			if (boton.getTipoFuncion() == TipoFuncion.MODIFICAR) {
				boton.setVisible(mostrar);
			}
		}
	}
	
	public void setMostrarModificar(boolean estado) {
		configurarModificar(estado);
	}
	
	private void configurarEliminar(boolean mostrar) {
		for (BotonFuncion boton : funciones) {
			if (boton.getTipoFuncion() == TipoFuncion.ELIMINAR) {
				boton.setVisible(mostrar);
			}
		}
	}
	
	public void setMostrarEliminar(boolean estado) {
		configurarEliminar(estado);
	}
	
	private void configurarBuscar(boolean mostrar) {
		for (BotonFuncion boton : funciones) {
			if (boton.getTipoFuncion() == TipoFuncion.BUSCAR) {
				boton.setVisible(mostrar);
			}
		}
	}
	
	public void setMostrarBuscar(boolean estado) {
		configurarBuscar(estado);
	}

	public void setMostrarSalir(boolean mostrarSalir) {
		this.mostrarSalir = mostrarSalir;
		configurarSalir(mostrarSalir);
	}
	
	public void setMostrarAceptar(boolean mostrarAceptar) {
		this.mostrarAceptar = mostrarAceptar;		
	}
	
	public void setMostrarCancelar(boolean mostrarCancelar) {
		this.mostrarCancelar = mostrarCancelar;		
	}
	
	public void setMostrarImprimir(boolean estado) {
		configurarImprimir(estado);
	}
	
	private void configurarImprimir(boolean mostrar) {
		for (BotonFuncion boton : funciones) {
			if (boton.getTipoFuncion() == TipoFuncion.IMPRIMIR) {
				boton.setVisible(mostrar);
			}
		}
	}

	public String getTextoAyuda() {
		return textoAyuda;
	}

	public void setTextoAyuda(String textoAyuda) {
		this.textoAyuda = textoAyuda;
	}

	public List<BotonAccion> getAcciones() {
		return acciones;
	}

	public void setAcciones(List<BotonAccion> acciones) {
		this.acciones = acciones;
	}

	public boolean isMostrarAceptar() {
		return mostrarAceptar;
	}

	public boolean isMostrarCancelar() {
		return mostrarCancelar;
	}
}